<?php

namespace app\common\command;

use app\common\service\CodexPriceService;
use app\common\service\user\UserInvestmentService;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Db;
use app\common\service\user\UserBalanceLogService;

class DistributeMiningProfit extends Command
{
    protected function configure()
    {
        $this->setName('mining:profit')->setDescription('每4小时发放挖矿收益（以CODEx形式发放，基于codex_amount本金）');
    }

    protected function execute(Input $input, Output $output)
    {
        $now = time();
        $today = date('Y-m-d', $now); // 用于 profit_date 分天

        // 获取当前汇率（用于记录日志和审计）
        try {
            $currentPrice = app()->make(CodexPriceService::class)->getNewPrice();
        } catch (\Exception $e) {
            $output->writeln("[$now] ❌ 获取汇率失败: " . $e->getMessage());
            return;
        }
        $output->writeln("[$now] 当前汇率：1 CODE = {$currentPrice} USDT");

        // ✅ 查询待结算的投资记录
        $investments = Db::name('user_investment')
            ->where('status', 1)
//            ->where(function ($query) use ($now) {
//                $query->where('last_profit_time', '<=', $now - 3600)
//                    ->whereOr('last_profit_time', null);
//            })
            ->select()
            ->toArray();

        if (empty($investments)) {
            $output->writeln("[$now] 无待结算投资");
            return;
        }

        $updates = [];
        $profitLogs = [];
        $balanceLogService = app()->make(UserBalanceLogService::class);

        // codex最新价格
        $codexPriceService = app()->make(CodexPriceService::class);
        $newCodexPrice = $codexPriceService->getNewPrice();

        // 获取机制收益比例
        $mechanisms = Db::name('mechanism')->where('status', 1)->column('profit_ratio', 'mode');

        foreach ($investments as $inv) {
            $userId = $inv['user_id'];

            $codexPrincipal = (float)$inv['usdt_amount'];     // ✅ 本金是 USDT 数量
//            $codexPrincipal = (float)$inv['codex_amount'];     // ✅ 本金是 CODEx 数量

            // 1. 买入固定收益比例
//            $dailyRate = (float)$inv['profit_ratio'] / 100;    // 日利率转小数（如 1% → 0.01）

            // 2. 根据后台调动
            $dailyRate = $mechanisms[$inv['mode']] / 100;

            $lastTime = (int)$inv['last_profit_time'] ?: $inv['invest_time'];
            $elapsedSeconds = $now - $lastTime;

            // 固定每4小时发放一次（即使时间差不足也发，但按比例算）
            $expectedInterval = 4 * 3600;
//            $profitFactor = min(1.0, $elapsedSeconds / $expectedInterval); // 防止超发
//            $codexProfit = $codexPrincipal * $dailyRate * ($expectedInterval / 86400) * $profitFactor;
            $codexProfit = $codexPrincipal * $dailyRate / $newCodexPrice / 6;
            $codexProfit = round($codexProfit, 8);

            if ($codexProfit < 0.00000001) continue;

            // ✅ 更新用户 CODEx 余额
            Db::name('user_account')
                ->where('user_id', $userId)
                ->inc('codex_balance', $codexProfit)
                ->update();

            // ✅ 更新投资记录中的累计收益（以 CODE 计）
            $newTotalCodexProfit = round((float)$inv['total_codex_profit'] + $codexProfit, 8);

            $updates[] = [
                'id' => $inv['id'],
                'total_codex_profit' => $newTotalCodexProfit,
                'last_profit_time' => $now,
                'update_time' => $now,
            ];

            // 折合 USDT 价值
            $usdtValue = $codexProfit * $currentPrice;

            // ✅ 构造新表 cc_user_mining_profit_log 数据
            $profitLogs[] = [
                'user_id' => $userId,
                'investment_id' => $inv['id'],
                'plan_id' => $inv['mechanism_id'] ?? 0,
                'profit_date' => $today,
                'mode' => $inv['mode'],
                'hash_rate' => $inv['hash_rate'] ?? 0.0,
                'daily_rate' => $dailyRate,
                'profit_amount' => $codexProfit,
                'codex_price_usdt' => $currentPrice,
                'profit_amount_usdt' => round($usdtValue, 8),
                'release_status' => 'success',
                'release_time' => $now,
                'create_time' => $now,
            ];

            // ✅ 更新用户收益汇总表
            $res = Db::name('user_income_summary')->where('user_id', $userId)->find();
            if (empty($res)) {
                Db::name('user_income_summary')->insert([
                    'user_id' => $userId,
                    'total_mining_profit_codex' => 0,
                    'last_update_time' => $now,
                ]);
            }

            Db::name('user_income_summary')
                ->where('user_id', $userId)
                ->inc('total_mining_profit_codex', $codexProfit)
                ->update([
                    'last_update_time' => $now
                ]);
        }

        if (empty($profitLogs)) {
            $output->writeln("[$now] 无有效收益产生");
            return;
        }

        // ✅ 事务提交：批量更新投资记录 + 插入新日志
        try {
            Db::transaction(function () use ($updates, $profitLogs) {
                foreach ($updates as $update) {
                    Db::name('user_investment')
                        ->where('id', $update['id'])
                        ->update([
                            'total_codex_profit' => $update['total_codex_profit'],
                            'last_profit_time' => $update['last_profit_time'],
                            'update_time' => $update['update_time'],
                        ]);
                }

                Db::name('user_mining_profit_log')->insertAll($profitLogs);
            });

            $output->writeln("[$now] 成功发放 CODEx 收益，共处理 " . count($profitLogs) . " 条");

            // ===================================================================
            // ✅ 【重点】开始合并记录到 user_balance_log（按 user_id + mode）
            // ===================================================================
            $summary = []; // [user_id][mode] => total_codex

            foreach ($profitLogs as $log) {
                $userId = $log['user_id'];
                $mode = $log['mode'];
                $amount = $log['profit_amount'];

                if (!isset($summary[$userId])) {
                    $summary[$userId] = [];
                }
                $summary[$userId][$mode] = ($summary[$userId][$mode] ?? 0) + $amount;
            }

            $count = 0;
            foreach ($summary as $userId => $modes) {
                foreach ($modes as $mode => $totalCodex) {
                    $totalCodex = round($totalCodex, 8);
                    if ($totalCodex < 0.00000001) continue;

                    // 根据 mode 确定业务类型
                    $bizType = '';
                    if ($mode == 1) {
                        $bizType = 'liquidity_income';
                        $modeText = '流动性';
                    } elseif ($mode == 2) {
                        $bizType = 'content_casting_revenue';
                        $modeText = '内容铸造';
                    } else {
                        continue; // 忽略非法 mode
                    }

                    // 统计该用户该模式下有多少笔投资
                    $detailCount = count(array_filter($profitLogs, function ($x) use ($userId, $mode) {
                        return $x['user_id'] == $userId && $x['mode'] == $mode;
                    }));

                    $remark = $modeText . "挖矿收益汇总: {$totalCodex} CODEX ({$detailCount}笔)";
                    $uniqueBizId = "{$modeText}_{$userId}_{$mode}_" . date('YmdH', $now); // 每小时唯一

                    try {
                        $balanceLogService->addLog(
                            $userId,
                            $bizType,
                            'codex',
                            $totalCodex,
                            $uniqueBizId,
                            $remark
                        );
                        $count++;
                    } catch (\Exception $e) {
                        $output->writeln("📒 用户 #{$userId} 余额日志写入失败: " . $e->getMessage());
                    }
                }
            }

            $output->writeln("[$now] 已合并生成 {$count} 条 user_balance_log 记录");

        } catch (\Exception $e) {
            $output->writeln("[$now] ❌ 事务执行失败: " . $e->getMessage());
        }
    }
}